package dyyx.http;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.handler.codec.http.multipart.Attribute;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.handler.codec.http.multipart.InterfaceHttpData;
import io.netty.util.CharsetUtil;
import io.netty.util.ReferenceCountUtil;

public class HttpServerHandler2 extends SimpleChannelInboundHandler<FullHttpRequest> {

	private static final String UTF8 = "utf-8";

	private static final String CONTENT_TYPE = "Content-Type";
	private static final String CONTENT_LENGTH = "Content-Length";
	private static final String CONNECTION = "Connection";
	private static final String KEEP_ALIVE = "keep-alive";

	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) {
		ctx.flush();
	}

	@Override
	public void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) {

		// req.getMethod();

		ByteBuf buf = req.content();
		
		String content = buf.toString(CharsetUtil.UTF_8);
		// post 可获取表单参数  q=a&s=b
		//   q=%E8%80%81%E8%99%8E&s=b 
		System.out.println("content="+content);

		
		String requestStr = parseRequestString(req);
		// String result = req.getDecoderResult().toString();
		String result = requestStr + " " + System.currentTimeMillis();
		// result = result +" " + System.currentTimeMillis();
		result = result + ",method=" + req.getMethod();
		result = result + ",uri=" + req.getUri();

		Map<String, String> headmap = new HashMap<String, String>();
		HttpHeaders heads = req.headers();

		for (Map.Entry<String, String> item : heads) {
			headmap.put(item.getKey(), item.getValue());
		}
		// 将GET, POST所有请求参数转换成Map对象
		// Map<String, String> parmMap = new RequestParser(req).parse();

		result = result + ",heads=" + headmap;

		Map<String, String> reqmap = getRequestMap(req);
		result = result + ",reqmap=" + reqmap;
		result = result + ",reqmap=" + reqmap+",content="+content;


		// 向客户端发送结果
		doResponse(ctx, req, result);
		
		// TODO  是否需要 release
	    // req.release();
		// SimpleChannelInboundHandler  channelRead  finally 里 做了 release
		// if (autoRelease && release) {ReferenceCountUtil.release(msg);}

	}

	/**
	 * 响应HTTP的请求
	 * 
	 * @param ctx
	 * @param req
	 * @param jsonStr
	 */
	private void doResponse(ChannelHandlerContext ctx, FullHttpRequest req, String result) {

		// boolean keepAlive = HttpUtil.isKeepAlive(req);
		boolean keepAlive = true;
		// byte[] jsonByteByte = jsonStr.getBytes();
		byte[] resultBytes = getBytes(result);
		
		FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
				Unpooled.wrappedBuffer(resultBytes));
		// text/json
		// response.headers().set(CONTENT_TYPE, "text/html");
		//
		response.headers().set(CONTENT_TYPE, "text/html;charset=utf-8");
		// response.headers().setInt(CONTENT_LENGTH,
		// response.content().readableBytes());
		response.headers().set(CONTENT_LENGTH, response.content().readableBytes());

		if (!keepAlive) {
			ctx.write(response).addListener(ChannelFutureListener.CLOSE);
			// System.out.println("keepAlive is false,close,"+new Date());
		} else {
			response.headers().set(CONNECTION, KEEP_ALIVE);

			ctx.write(response);
		}
		// TODO  write 与  writeAndFlush 有何区别
		// ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
		//  channelReadComplete 里 调用了 
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
		cause.printStackTrace();
		ctx.close();
	}

	/**
	 * 获取请求的内容
	 * 
	 * @param request
	 * @return
	 */
	private String parseRequestString(FullHttpRequest request) {
		ByteBuf buf = request.content();
		String str = buf.toString(CharsetUtil.UTF_8);
		return str;
	}

	private static byte[] getBytes(String str) {
		try {
			return str.getBytes(UTF8);
		} catch (Throwable e) {
			return new byte[0];
		}
	}

	public static Map<String, String> getRequestMap(FullHttpRequest req) {

		// Map<String, String> map = new HashMap<String,String>();
		HttpMethod method = req.getMethod();

		Map<String, String> parmMap = new HashMap<>();

		if (HttpMethod.GET == method) {

			String requri = req.getUri();
			System.out.println("requestUri=" + requri);

			// 是GET请求
			QueryStringDecoder decoder = new QueryStringDecoder(requri, CharsetUtil.UTF_8);
			// System.out.println("requestUri="+decoder.getc);

			/*
			 * decoder.parameters().entrySet().forEach( entry -> { //
			 * entry.getValue()是一个List, 只取第一个元素 parmMap.put(entry.getKey(),
			 * entry.getValue().get(0)); });
			 */
			Map<String, List<String>> qmap = decoder.parameters();
			Set<Entry<String, List<String>>> eset = qmap.entrySet();
			List<String> list = null;
			String key = null;

			for (Entry<String, List<String>> item : eset) {
				key = item.getKey();
				list = item.getValue();
				if (list.size() > 0) {
					parmMap.put(key, list.get(0));
				}
			}

		} else if (HttpMethod.POST == method) {
			// 是POST请求
			HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(req);
			decoder.offer(req);
			
			// TODO decoder.isMultipart()

			System.out.println("post.decoder.toString()="+decoder.toString());

			// TODO 
			// decoder.getBodyHttpDatas(name);
						
			// 表单参数 ！！！
			List<InterfaceHttpData> dataList = decoder.getBodyHttpDatas();

			for (InterfaceHttpData item : dataList) {

				// Attribute data = (Attribute) parm;
				// parmMap.put(data.getName(), data.getValue());
				// bodyHttpData=Mixed: name=tiger,class
				// io.netty.handler.codec.http.multipart.MixedAttribute,Attribute
				// bodyHttpData=Mixed: age=7,class
				// io.netty.handler.codec.http.multipart.MixedAttribute,Attribute

				System.out.println("bodyHttpData=" + item + "," + item.getClass() + "," + item.getHttpDataType());

				if (item instanceof Attribute) {
					Attribute dataitem = (Attribute) item;
					String value = getValue(dataitem);
					if (value == null) {
						continue;
					}
					parmMap.put(dataitem.getName(), value);
				}

			}

		} else {
			// 不支持其它方法
			// throw new MethodNotSupportedException(""); // 这是个自定义的异常, 可删掉这一行
			throw new RuntimeException("notSupportMethod," + method);
		}

		return parmMap;
	}

	private static String getValue(Attribute attr) {
		if (attr == null) {
			return null;
		}
		try {
			return attr.getValue();
		} catch (Throwable e) {
			return null;
		}
	}

}
